package jmt.engine.QueueNet;

import java.util.ArrayList;
import java.util.List;

import jmt.engine.NetStrategies.QueuePutStrategy;
import jmt.engine.NetStrategies.ServiceStrategy;
import jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy;
import jmt.engine.NetStrategies.RoutingStrategies.RandomStrategy;
import jmt.engine.NetStrategies.ServiceStrategies.ServiceTimeStrategy;
import jmt.engine.NodeSections.Queue;
import jmt.engine.NodeSections.Router;
import jmt.engine.NodeSections.Server;
import jmt.engine.NodeSections.ServiceTunnel;
import jmt.engine.random.Distribution;
import jmt.engine.random.Exponential;
import jmt.engine.random.ExponentialPar;
import jmt.engine.random.Parameter;
import jmt.engine.simEngine.Simulation;

/**
 * 
 * @author Riccardo Pinciroli
 *
 */

public class EnergyOptimizer {
	
	protected String name;
	protected List<String> sourcesName = new ArrayList<String>();
	protected List<String> targetsName = new ArrayList<String>();
	
	protected Simulation sim;
	protected QueueNetwork network;
	
	//protected String[] blockNodeNames;
	protected NetNode[] blockNodes;

	protected BlockingRegion[] regions;
	
	protected boolean[] dropClass; //Sarà tutto a falso perché dobbiamo mantenere i job e non scartarli
	
	//------------------------------CONSTRAINTS------------------------------\\
	protected double numRegions; //Moltiplicando per 2 ho anche il numero delle stazioni
	protected double[] windowSize;
	protected double[] aging;
	protected double[] maxCapacity;
	protected double[][] betaPerClass;
	
	protected double actualOccupation;
	protected double[] actualBetaPerClass;
	//------------------------------END CONSTRAINTS------------------------------\\
	
	//------------------
	
//	public EnergyOptimizer(String name, double[] maxCapacity, double[][] betaPerClass, double[] windowSize, double[] aging, double numRegions, NetNode[] stationsInBlock, Simulation simul) {
//		
//		this.name = name;
//		this.sim = simul;
//		int classNumber = sim.getClasses().length;
//		
//		for(int i=0; i<classNumber; i++) {
//			dropClass[i] = false;
//		}
//		
//		//this.blockNodeNames = new String[(int) numRegions*2];
//		this.blockNodes = stationsInBlock;		
////		for(int i=0; i<numRegions*2; i++) {
////			blockNodeNames[i] = "Station_In_Block_"+i;
////			blockNodes[i] = new NetNode(blockNodeNames[i]);
////		}
//		
//		for(int i=0; i<numRegions; i++) {
//			String[] regionNodeNames = {blockNodes[i].getName(), blockNodes[(int) numRegions+i].getName()};
//			//regionNodeNames[0] = blockNodeNames[i];
//			//regionNodeNames[1] = blockNodeNames[(int) numRegions+i];
//			regions[i] = new BlockingRegion("FCR_"+i, maxCapacity[i], betaPerClass[i], dropClass, sim, regionNodeNames);
//		}
//	}
	
	//------------------
	
	public EnergyOptimizer(String name, List<String> sourcesNames, List<String> targetsName, Simulation sim) {
			this.sim = sim;
			this.name = name;
			this.sourcesName = sourcesNames;
			this.targetsName = targetsName;
	}
	
	public String getName() {
		return name;
	}
	
//	public void createInnerStations() {
//		try {			
//			QueuePutStrategy[] putStrategy = new QueuePutStrategy[sim.getClasses().length];
//			Distribution[] serverExp = new Distribution[sim.getClasses().length];
//			Parameter[] serverPar = new Parameter[sim.getClasses().length];
//			ServiceStrategy[] serverStrategy = new ServiceStrategy[sim.getClasses().length];
//			RandomStrategy[] routerStrategy = new RandomStrategy[sim.getClasses().length];
//			
//			for(int i=0; i<sim.getClasses().length; i++) {
//				putStrategy[i] = new TailStrategy();
//				serverExp[i] = new Exponential();
//				serverPar[i] = new ExponentialPar(1.0);
//				serverStrategy[i] = new ServiceTimeStrategy(serverExp[i], serverPar[i]);
//				routerStrategy[i] = new RandomStrategy();
//			}
//			
//			sim.addNode(this.name+"_router1", new Queue(-1, false, null, putStrategy), new ServiceTunnel(), new Router(routerStrategy));
//			sim.addNode(this.name+"_server1", new Queue(-1, false, null, putStrategy), new Server(1, null, serverStrategy), new Router(routerStrategy));
//			sim.addNode(this.name+"_server2", new Queue(-1, false, null, putStrategy), new Server(1, null, serverStrategy), new Router(routerStrategy));
//			sim.addNode(this.name+"_server3", new Queue(-1, false, null, putStrategy), new Server(1, null, serverStrategy), new Router(routerStrategy));
//			
//			for(int i=0; i<sourcesName.size(); i++) {
//				sim.addConnection(sourcesName.get(i), this.name+"_router1");
//				System.out.println("EnergyOptimizer(117) -> Una source è: "+sourcesName.get(i));
//			}
////			sim.addConnection("Source 1", this.name+"_router1");
//			sim.addConnection(this.name+"_router1", this.name+"_server1");
//			sim.addConnection(this.name+"_router1", this.name+"_server2");
//			sim.addConnection(this.name+"_router1", this.name+"_server3");
//			for(int i=0; i<targetsName.size(); i++) {
//				sim.addConnection(this.name+"_server1", targetsName.get(i));
//				sim.addConnection(this.name+"_server2", targetsName.get(i));
//				sim.addConnection(this.name+"_server3", targetsName.get(i));
//				System.out.println("EnergyOptimizer(127) -> Un target è: "+targetsName.get(i));
//			}
////			sim.addConnection(this.name+"_server1", "Sink 1");
////			sim.addConnection(this.name+"_server2", "Sink 1");
////			sim.addConnection(this.name+"_server3", "Sink 1");
//			System.out.println("EnergyOptimizer(133) -> Stazioni e connessioni sono state create nell'energyOptimizer "+this.getName());
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}
}

